package json

import (
	"encoding/json"
	jsoniter "github.com/json-iterator/go"
	"github.com/json-iterator/go/extra"
	"io"
	"sieve_admin_server_userpass/lib/config"
)

var (
	fUseStd   = config.Bool("lib.json.usestd", false, "")
	fFuzzType = config.Bool("lib.json.jsonit.fuzztype", false, "")

	jsoni = jsoniter.Config{
		EscapeHTML:             true,
		SortMapKeys:            true,
		ValidateJsonRawMessage: true,
		CaseSensitive:          *config.Bool("lib.json.jsonit.casesens", false, ""),
	}.Froze()
)

func init() {
	if *fFuzzType {
		extra.RegisterFuzzyDecoders()
	}
}

type RawMessage = json.RawMessage

func Marshal(v any) ([]byte, error) {
	if *fUseStd {
		return json.Marshal(v)
	}
	return jsoni.Marshal(v)
}

func Unmarshal(data []byte, v any) error {
	if *fUseStd {
		return json.Unmarshal(data, v)
	}
	return jsoni.Unmarshal(data, v)
}

func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
	if *fUseStd {
		return json.MarshalIndent(v, prefix, indent)
	}
	return jsoni.MarshalIndent(v, prefix, indent)
}

type Encoder interface {
	Encode(v any) error
	SetIndent(prefix, indent string)
	SetEscapeHTML(on bool)
}

func NewEncoder(w io.Writer) Encoder {
	if *fUseStd {
		return json.NewEncoder(w)
	}
	return jsoni.NewEncoder(w)
}

type Decoder interface {
	Decode(v any) error
	Buffered() io.Reader
	UseNumber()
	DisallowUnknownFields()
	More() bool
}

func NewDecoder(r io.Reader) Decoder {
	if *fUseStd {
		return json.NewDecoder(r)
	}
	return jsoni.NewDecoder(r)
}
